package curves.math;

import java.util.ArrayList;
import java.util.List;
import curves.CurveAlgorithm;
import curves.Point;
import curves.sys.MPoint;

public class ChaikinCurveAlgorithm implements CurveAlgorithm {

    @Override
    public List<Point> calculatePoints(List<Point> initialPoints, boolean open, int steps, int start, int end) {
        ArrayList<Point> rpoints = new ArrayList<Point>();
        rpoints.clear();
        rpoints.addAll(initialPoints);

        ArrayList<Point> store = new ArrayList<Point>();

        if (open == false) {
            rpoints.add(initialPoints.get(0));
        }

        Point first = rpoints.get(0);
        Point last = rpoints.get(rpoints.size() - 1);

        for (int j = 0; j < steps; j++) {
            store.clear();


            for (int i = 0; i + 1 < rpoints.size(); i++) {

                if ((i != 0) && open || !open) {
                    double x1 = rpoints.get(i).getX() + 1.0 / 4.0 * (rpoints.get(i + 1).getX() - rpoints.get(i).getX());
                    double y1 = rpoints.get(i).getY() + 1.0 / 4.0 * (rpoints.get(i + 1).getY() - rpoints.get(i).getY());

                    Point p1 = new MPoint(x1, y1);

                    store.add(p1);
                }

                if ((i + 2 != rpoints.size()) && open || !open) {
                    double x2 = rpoints.get(i).getX() + 3.0 / 4.0 * (rpoints.get(i + 1).getX() - rpoints.get(i).getX());
                    double y2 = rpoints.get(i).getY() + 3.0 / 4.0 * (rpoints.get(i + 1).getY() - rpoints.get(i).getY());

                    Point p2 = new MPoint(x2, y2);

                    store.add(p2);
                }
            }

            rpoints.clear();
            rpoints.addAll(store);

            if (open) {
                rpoints.add(0, first);
                rpoints.add(last);

            } else {
                rpoints.add(store.get(0));
            }
        }

        return rpoints;
    }

    @Override
    public String toString() {
        return "Chaikin";
    }
}
